package com.aruba.socketlibrary.utils;

import java.io.ByteArrayOutputStream;
import java.io.File;
import java.io.FileInputStream;
import java.nio.ByteBuffer;

import static android.os.Environment.getExternalStorageDirectory;

/**
 * Created by aruba on 2017/10/19.
 */

public class Tools {

    /**
     * bytes转换成十六进制字符串
     *
     * @param b byte数组
     * @return String 每个Byte值之间空格分隔
     */
    public static String byte2HexStr(byte[] b) {
        String stmp = "";
        StringBuilder sb = new StringBuilder("");
        for (int n = 0; n < b.length; n++) {
            stmp = Integer.toHexString(b[n] & 0xFF);
            sb.append((stmp.length() == 1) ? "0" + stmp : stmp);
            sb.append(" ");
        }
        return sb.toString().toUpperCase().trim();
    }

    /**
     * bytes转换成十六进制字符串
     *
     * @param b byte
     * @return String 每个Byte值之间空格分隔
     */
    public static String byte2HexStr(byte b) {
        String stmp = "";
        StringBuilder sb = new StringBuilder("");
        stmp = Integer.toHexString(b & 0xFF);
        sb.append((stmp.length() == 1) ? "0" + stmp : stmp);
        sb.append(" ");
        return sb.toString().toUpperCase().trim();
    }

    public static String byteToHexString(byte[] bArray, final int size) {
        StringBuffer sb = new StringBuffer(size + size / 2);
        String sTemp;
        for (int i = 0; i < size; i++) {
            sTemp = Integer.toHexString(0xFF & bArray[i]);
            if (sTemp.length() < 2)
                sb.append(0);
            sb.append(sTemp.toUpperCase());
            sb.append(' ');
        }
        return sb.toString();
    }

    // 从字节数组到转换十六进制字符串
    public static String bytesToHexString(byte[] data, int offset, int count) {
        String str = "";
        for (int i = 0; i < count; i++) {
            str += String.format("%02X", data[offset + i]);
        }
        return str;
    }

    // 从十六进制字符串到字节数组转换
    public static byte[] hexString2Bytes(String hexString) {
        hexString = hexString.replace(" ", "");
        if (hexString == null || hexString.equals("")) {
            return null;
        }
        hexString = hexString.toUpperCase();
        int length = hexString.length() / 2;
        char[] hexChars = hexString.toCharArray();
        byte[] d = new byte[length];
        for (int i = 0; i < length; i++) {
            int pos = i * 2;
            d[i] = (byte) (charToByte(hexChars[pos]) << 4 | charToByte(hexChars[pos + 1]));
        }
        return d;
    }


    public static byte charToByte(char c) {
        return (byte) "0123456789ABCDEF".indexOf(c);
    }

    // 计算校验码
    public static byte Xor(byte[] data, int offset, int count) {
        byte val = data[offset];
        for (int i = offset + 1; i < count; i++) {
            val = (byte) (val ^ data[i]);
        }
        return val;
    }

    public static int makeCheckSum(byte[] paramArrayOfByte) {
        int i = 0;
        if (paramArrayOfByte.length >= 3) {
            i = 0;
        }
        for (int j = 2; ; j++) {
            if (j >= -3 + paramArrayOfByte.length) {
                return (byte) i;
            }
            i = (byte) (i ^ paramArrayOfByte[j]);
        }
    }

    /**
     * 11转0x11
     *
     * @param old
     * @return
     */
    public static int ten2sixteen(int old) {
        return Integer.parseInt(old + "", 16);
    }

    public static String AsciiByte2String(byte[] bytes) {
        StringBuffer tStringBuf = new StringBuffer();

        char[] tChars = new char[bytes.length];

        for (int i = 0; i < bytes.length; i++)
            tChars[i] = (char) bytes[i];

        tStringBuf.append(tChars);
        return tStringBuf.toString();
    }

    public static byte[] stringToAscii(String value) {
        char[] chars = value.toCharArray();
        byte[] bytes = new byte[chars.length];

        for (int i = 0; i < chars.length; i++) {
            bytes[i] = (byte) chars[i];
        }
        return bytes;
    }

    public static String gbk2utf8(String gbk) {
        String l_temp = GBK2Unicode(gbk);
        l_temp = unicodeToUtf8(l_temp);

        return l_temp;
    }

    public static String utf82gbk(String utf) {
        String l_temp = utf8ToUnicode(utf);
        l_temp = Unicode2GBK(l_temp);

        return l_temp;
    }

    /**
     * @param str
     * @return String
     */

    public static String GBK2Unicode(String str) {
        StringBuffer result = new StringBuffer();
        for (int i = 0; i < str.length(); i++) {
            char chr1 = (char) str.charAt(i);

            if (!isNeedConvert(chr1)) {
                result.append(chr1);
                continue;
            }

            result.append("\\u" + Integer.toHexString((int) chr1));
        }

        return result.toString();
    }

    /**
     * @param dataStr
     * @return String
     */

    public static String Unicode2GBK(String dataStr) {
        int index = 0;
        StringBuffer buffer = new StringBuffer();

        int li_len = dataStr.length();
        while (index < li_len) {
            if (index >= li_len - 1
                    || !"\\u".equals(dataStr.substring(index, index + 2))) {
                buffer.append(dataStr.charAt(index));

                index++;
                continue;
            }

            String charStr = "";
            charStr = dataStr.substring(index + 2, index + 6);

            char letter = (char) Integer.parseInt(charStr, 16);

            buffer.append(letter);
            index += 6;
        }

        return buffer.toString();
    }

    public static boolean isNeedConvert(char para) {
        return ((para & (0x00FF)) != para);
    }

    /**
     * utf-8 转unicode
     *
     * @param inStr
     * @return String
     */
    public static String utf8ToUnicode(String inStr) {
        char[] myBuffer = inStr.toCharArray();

        StringBuffer sb = new StringBuffer();
        for (int i = 0; i < inStr.length(); i++) {
            Character.UnicodeBlock ub = Character.UnicodeBlock.of(myBuffer[i]);
            if (ub == Character.UnicodeBlock.BASIC_LATIN) {
                sb.append(myBuffer[i]);
            } else if (ub == Character.UnicodeBlock.HALFWIDTH_AND_FULLWIDTH_FORMS) {
                int j = (int) myBuffer[i] - 65248;
                sb.append((char) j);
            } else {
                int s = (int) myBuffer[i];
                String hexS = Integer.toHexString(s);
                String unicode = "\\u" + hexS;
                sb.append(unicode.toLowerCase());
            }
        }
        return sb.toString();
    }

    /**
     * @param theString
     * @return String
     */
    public static String unicodeToUtf8(String theString) {
        char aChar;
        int len = theString.length();
        StringBuffer outBuffer = new StringBuffer(len);
        for (int x = 0; x < len; ) {
            aChar = theString.charAt(x++);
            if (aChar == '\\') {
                aChar = theString.charAt(x++);
                if (aChar == 'u') {
                    // Read the xxxx  
                    int value = 0;
                    for (int i = 0; i < 4; i++) {
                        aChar = theString.charAt(x++);
                        switch (aChar) {
                            case '0':
                            case '1':
                            case '2':
                            case '3':
                            case '4':
                            case '5':
                            case '6':
                            case '7':
                            case '8':
                            case '9':
                                value = (value << 4) + aChar - '0';
                                break;
                            case 'a':
                            case 'b':
                            case 'c':
                            case 'd':
                            case 'e':
                            case 'f':
                                value = (value << 4) + 10 + aChar - 'a';
                                break;
                            case 'A':
                            case 'B':
                            case 'C':
                            case 'D':
                            case 'E':
                            case 'F':
                                value = (value << 4) + 10 + aChar - 'A';
                                break;
                            default:
                                throw new IllegalArgumentException(
                                        "Malformed   \\uxxxx   encoding.");
                        }
                    }
                    outBuffer.append((char) value);
                } else {
                    if (aChar == 't')
                        aChar = '\t';
                    else if (aChar == 'r')
                        aChar = '\r';
                    else if (aChar == 'n')
                        aChar = '\n';
                    else if (aChar == 'f')
                        aChar = '\f';
                    outBuffer.append(aChar);
                }
            } else
                outBuffer.append(aChar);
        }
        return outBuffer.toString();
    }

    public static int reverse(int s) {
        int d = 0;
        for (int i = 0; i < 32; i++) {//
            d += ((s >> i) & 0x01) << 31 - i;
        }

        return d;
    }

    public static byte[] intToByteArray(final int integer) {
        int byteNum = (40 - Integer.numberOfLeadingZeros(integer < 0 ? ~integer : integer)) / 8;
        byte[] byteArray = new byte[4];

        for (int n = 0; n < byteNum; n++)
            byteArray[3 - n] = (byte) (integer >>> (n * 8));

        return (byteArray);
    }

    public static byte[] byteExtend(byte[] bytes, int length) {
        ByteBuffer byteArray = ByteBuffer.allocate(length);
        byteArray.put(bytes, 0, length);

        return byteArray.array();
    }

    public static String getTmpPath(String driverCode) {
        return getExternalStorageDirectory() + "/KPOCOM/QR/" + driverCode + ".tmp";
    }

    public static String getPhotoPath(String driverCode) {
        return getExternalStorageDirectory() + "/KPOCOM/QR/" + driverCode + ".jpg";
    }

    //获得指定文件的byte数组 
    public static byte[] getBytes(String filePath) throws Exception {
        byte[] buffer = null;
        File file = new File(filePath);
        FileInputStream fis = new FileInputStream(file);
        ByteArrayOutputStream bos = new ByteArrayOutputStream(1000);
        byte[] b = new byte[1000];
        int n;
        while ((n = fis.read(b)) != -1) {
            bos.write(b, 0, n);
        }
        fis.close();
        bos.close();
        buffer = bos.toByteArray();
        return buffer;
    }
}
